use std::io::Read;
use tokio::fs::{File, OpenOptions, metadata, remove_file};
use tokio::io::{self, AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter};
use std::path::Path;
use std::rc::Rc;
use crate::ltools::lstring;



/* 读取文件内容 */
pub(crate) async fn read_file_line(path:&str,f:fn(&str)) -> io::Result<()>{
    let open_file = File::open(path).await?;
    // 创建一个缓冲读取器
    let mut reader = BufReader::with_capacity(1024, open_file);

    let mut line = String::new();
    while reader.read_line(&mut line).await? > 0 {
        f(&line);
        line.clear(); // 清空字符串，以便下一次读取
    }
    Ok(())
}

/* 逐个字符的读取 */
pub(crate) async fn read_file(path:&str) -> io::Result<()>{
    let open_file = File::open(path).await?;
    let mut reader = BufReader::with_capacity(1024, open_file);

    loop {
        let mut lens = 0;
        {
            let buf = reader.fill_buf().await?;
            if buf.is_empty() {
                break;
            }
            lens = buf.len();
        }
        // 消耗已读取的数据
        reader.consume(lens);
    }

    Ok(())
}

pub(crate) async fn write_file_byte(path: &str, content: &[u8], if_append: bool) -> io::Result<()> {
    let option_file = OpenOptions::new()
        .write(true)
        .append(if_append)
        .create(true)
        .open(path).await?;

    let mut writer: BufWriter<File> = BufWriter::new(option_file);
    writer.write_all(content).await.unwrap();
    writer.flush().await.unwrap();
    return Ok(());
}

/**
 * 写入文件，如果文件不存在就新建一个文件
 * path 文件地址
 * content 写入内容
 * if_append 是否在后面追加
 */
pub(crate) async  fn write_file(path: &str, content: &str, if_append: bool) -> io::Result<()> {
    write_file_byte(path, content.as_bytes(), if_append).await?;
    return Ok(());
}

/**
 * 读取地址中的全部文件
 */
pub(crate) async fn read_all_file(path: &str) -> io::Result<Vec<(String, String)>> {
    return read_all_file_path(Path::new(path)).await;
}

/**
 * 读取文件夹中的全部文件
 */
pub(crate) async fn read_all_file_path
(path: &Path) -> io::Result<Vec<(String, String)>> {

    let mut file_list:Vec<(String, String)> = Vec::new();
    for entity in std::fs::read_dir(path)? {
        let entity = entity?;
        let path: std::path::PathBuf = entity.path();
        if entity.file_type()?.is_dir() {
            // read_all_file_path(path.as_path())?;
            continue;
        }
        let path_str = path.file_name().unwrap().to_str().unwrap();
        let path_parent = path.parent().unwrap().to_str().unwrap();

        file_list.push((format!("{}/{}", path_parent, path_str), path_str.to_string()));
    }
    return Ok(file_list);
}

/* 判断文件大小 */
pub(crate) async  fn file_size(path: &str) -> u64{
    match  metadata(path).await {
        Ok(m ) => {
            m.len()
        }
        Err(_e) =>{
            0
        }
    }
}

/* 删除文件 */
pub(crate) async  fn delete(path:&str) {
    match remove_file(path).await {
        Ok(m) => {}
        Err(_e) => {}
    }
}
















